#pragma once

#include <windows.h>
#include <d3d11_1.h>
#include <d3dcompiler.h>
#include <directxcolors.h>
#include <vector>
#include "DDSTextureLoader.h"
#include "Model.h"
#include "Camera.h"
#include <DirectXMath.h>
#include <vector>
#include "PointLight.h"
#include "TextureTargetRenderer.h"
#include "LineList.h"

class GraphicsRenderer
{
public:
	GraphicsRenderer(HWND windowHandle, DirectX::XMFLOAT3 lightPosition1, DirectX::XMFLOAT3 lightPosition2);
	~GraphicsRenderer(void);
	void Render(void) const;
	HRESULT AddModel(Model& model);
	HRESULT AddLineList(LineList& lineList);
	HRESULT AddTexture(Texture& texture);
	void SetCamera(Camera* camera);
	void SwitchUseBumpMap( void );
	void SwitchRasterizer( void );
	void ApplyBumpinessChange( int change );
	void ApplyVertexChanges( Model* model );
	std::vector<Model*> GetRegisteredModels(void);
	void UpdateRay(LineList* ray);
	void UpdateKdTree(LineList* ktTree);
	void UpdateMeasurementLine(LineList* measurementLine);
	void ToggleShowKdTree(void);
	void StepAntiAliasingMode( void );
	void ToggleAntiAliasing( void );
	void ShowInfo(LPCWSTR info);
private:
	HRESULT m_CompileShaderFromFile( WCHAR* shaderFileName, LPCSTR shaderEntryPointName, LPCSTR shaderModel, ID3DBlob** shaderBinaryOut );
	HRESULT m_InitializeD3D(void);
	void m_ClearD3D(void);
	void m_ResetRenderTarget(void) const;
	void m_SetStandartShaders(void) const;
	void m_SetShadowMapShaders(void) const;
	void m_SetLineShaders(void) const;
	void m_RestartD3d(void);

	int m_windowWith, m_windowHeight;
	HWND m_windowHandle;
	ID3D11Device* m_d3dDevice;
	ID3D11DeviceContext* m_d3dContext;
	IDXGISwapChain* m_swapChain;
	ID3D11RenderTargetView* m_renderTargetView;
	ID3D11Texture2D* m_depthStencilBuffer;
	ID3D11DepthStencilView* m_depthStencilView;
	ID3D11VertexShader* m_lineVertexShader;
	ID3D11PixelShader* m_linePixelShader;
	ID3D11VertexShader* m_vertexShader;
	ID3D11PixelShader* m_pixelShader;
	ID3D11VertexShader* m_shadowMapVertexShader;
	ID3D11PixelShader* m_shadowMapPixelShader;
	ID3D11InputLayout* m_shaderInputLayout;
	ID3D11InputLayout* m_coloredLineShaderInputLayout;
	ID3D11Buffer* m_cbView;
	ID3D11Buffer* m_cbProjection;
	ID3D11Buffer* m_cbModel;
	ID3D11Buffer* m_cbLight1;
	ID3D11Buffer* m_cbLight2;
	ID3D11Buffer* m_cbOptions;
	ID3D11SamplerState* m_samplerStateLinear;
	ID3D11SamplerState* m_samplerStateClamp;
	DirectX::XMMATRIX m_viewMatrix;
	DirectX::XMMATRIX m_projectionMatrix;
	DirectX::XMFLOAT4 m_ModelColor;
	std::vector<Model*> m_models;
	std::vector<LineList*> m_lineLists;
	Camera* m_camera;
	PointLight m_pointLight1;
	TextureTargetRenderer m_shadowMap1Renderer;
	PointLight m_pointLight2;
	TextureTargetRenderer m_shadowMap2Renderer;
	ID3D11RasterizerState* m_standartRasterizerState;
	ID3D11RasterizerState* m_wireFrameRasterizerState;
	ID3D11RasterizerState* m_rasterizerStateActual;
	bool m_useBumpMaps;
	float m_bumpiness;
	LineList* m_ray;
	LineList* m_kdTree;
	LineList* m_measurementLine;
	bool m_showKdTree;
	std::vector<Texture*> m_textures;
	UINT m_antiAliasingCount;
	UINT m_antiAliasingQuality;
	bool m_antiAliasing;

	static const float M_PROJECTION_NEAR;
	static const float M_PROJECTION_FAR;
	static const int M_SHADOW_MAP_WIDTH;
	static const int M_SHADOW_MAP_HEIGHT;
};
